﻿using Abp.AspNetCore.Mvc.Controllers;
using Abp.Domain.Repositories;
using Batman.Cms.Core.Models.Mvc;
using Batman.Core;
using Batman.Jianbei.Forum.Core.ChatRoom;
using Batman.Jianbei.Forum.Core.Consts;
using Batman.Jianbei.Forum.DTOS.Chatroom;
using Batman.Jianbei.Forum.Services.ChatRoom;
using Batman.Jianbei.Forum.Services.ChatRoom.CacheQs;
using Batman.Jianbei.Forum.Services.Users;
using Batman.Jianbei.Forum.SignalR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using MongoDB.Driver;
using Omu.ValueInjecter;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Batman.Jianbei.Forum.Areas.ChatRoom
{
    [Authorize]
    [Area(RouteNames.ChatRoom)]
    public class RoomController : AbpController
    {
        public RoomService RoomService { get; set; }

        /// <summary>
        /// 匿名身份分配服务
        /// </summary>
        public RoomMaskService MaskDistributionService { get; set; }

        public IRepository<RoomMask, string> _roomMaskRepo { get; set; }

        public RoleCacheService RoleCacheService { get; set; }

        public SendTextMQ SendTextMQ { get; set; }

        public IHubContext<ChatHub> _hubContext { get; set; }

        public IRepository<Mask, string> maskRepo { get; set; }

        public RoomCacheQs RoomCacheQs { get; set; }

        [Authorize]
        public IActionResult Create(CreateRoomInput model)
        {
            var record = new TalkRoom();
            record.InjectFrom(model);
            record.CreateBy = User.GetWxUserId();

            var uid = User.GetWxUserId();
            var userId = User.GetUserId();

            var isAdminsRoom = RoleCacheService.GetAdminOrSupperAdminIds().Contains(userId);
            var result = isAdminsRoom ? RoomService.CreateAdminsRoom(record, uid) :
                                        RoomService.Create(record, uid);


            return Json(result);
        }

        /// <summary>
        /// 获取房间列表
        /// </summary>
        /// <returns></returns>
        public IActionResult RoomList()
        {
            var result = RoomService.GetRoomList();
            return Json(result);
        }



        #region 加入房间

        /// <summary>
        /// 加入房间，获取房间资料
        /// </summary>
        /// <param name="roomId"></param>
        /// <returns></returns>
        [Authorize]
        public IActionResult Join(string roomId, string msgId)
        {
            var uid = User.GetWxUserId();
            var joinResult = RoomService.Join(uid, roomId);
            return Json(joinResult);
        }

        #endregion

        /// <summary>
        /// 离开房间
        /// </summary>
        /// <param name="roomId"></param>
        /// <returns></returns>
        public IActionResult Leave(string roomId)
        {
            RoomService.Leave(roomId, User.GetWxUserId());
            return Content("ok");
        }

        /// <summary>
        /// 发送文本消息
        /// </summary>
        /// <param name="roomId"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public async Task<ResponseBase> SendText(string roomId, string text, string maskId)
        {
            var uid = User.GetWxUserId();
            var roomMask = _roomMaskRepo.GetQuery().Include(t => t.Mask)
                                                   .ThenInclude(t => t.Avatar)
                                                   .FirstOrDefault(t => t.RoomId == roomId && t.Uid == uid);

            if (roomMask.NotEntry) return new ResponseBase(-2, "您已被移除聊天室");

            var MQInput = new SendTextMQInput
            {
                RoomId = roomId,
                MaskId = maskId,
                Text = text,
                UId = uid
            };

            SendTextMQ.BasicPublish(MQInput);


            var mask = roomMask.Mask;

            var roomMsg = new RoomTextMsgDTO(roomId, mask, text);

            await _hubContext.Clients.All.SendAsync(roomMsg.GetMethod(), roomMsg);
            return new ResponseBase { Result = MQInput.MsgId };
        }

        /// <summary>
        /// 前端发送图片消息
        /// </summary>
        /// <param name="roomId"></param>
        /// <param name="serverId"></param>
        /// <returns></returns>
        public async Task<IActionResult> SendPic(string roomId, string serverId)
        {
            var uid = User.GetWxUserId();
            var result = await RoomService.SendPicMsg(uid, roomId, serverId);
            return Json(result);
        }

        /// <summary>
        /// 聊天室成员信息（含当前登录用户的信息）
        /// </summary>
        /// <param name="roomId"></param>
        public IActionResult RoomInfo(string roomId)
        {
            var uid = User.GetWxUserId();
            var result = RoomService.GetMembers(roomId, uid);
            return Json(result);
        }

        /// <summary>
        /// 房间成员报到接口
        /// </summary>
        /// <param name="roomId"></param>
        /// <param name="maskId"></param>
        /// <returns>签入的人</returns>
        [Authorize]
        public IActionResult CheckIn(string roomId, string maskId)
        {
            if (roomId == "undefined") return null;
            var uid = User.GetUserId();

            var roomMask = _roomMaskRepo.GetQuery().FirstOrDefault(t => t.RoomId == roomId && t.Uid == uid);
            if (roomMask != null)
            {
                _roomMaskRepo.Update(roomMask.Id, t =>
                {
                    t.CheckIn = DateTime.Now;
                    t.IsInRoom = true;
                }); // 更新最后报到时间
            }
            return Json(new ResponseBase());
        }

        /// <summary>
        /// 注销房间
        /// </summary>
        /// <param name="roomId"></param>
        /// <returns></returns>
        public ResponseBase Cancellation(string roomId)
        {
            var uid = User.GetWxUserId();
            var res = RoomService.Cancellation(roomId, uid);
            return res;
        }

        /// <summary>
        /// 踢人出房间
        /// </summary>
        /// <param name="roomId"></param>
        /// <returns></returns>
        public ResponseBase Kickout(string roomId, string maskId)
        {
            var uid = User.GetWxUserId();
            var res = RoomService.Kickout(roomId, maskId, uid);
            return res;
        }
    }
}